<?php

namespace Service\MoveUpDownService;

use Service\BaseService;
use Service\Code\Normal;
use Hyperf\DbConnection\Db;

class MoveUpDownService extends BaseService
{
    /**
     * 上下移动
     * $id 当前移动的id
     * $action 操作 up=上移 down=下移
     * $table 实例化的数据库
     * $sortField 表中排序字段
     */
    public function moveUpDown($id, $action, $table,$where, $sortField = 'sort'): array
    {

        if (empty($id) || empty($action) || empty($table) || empty($where)) {
            return Normal::returnCode(Normal::FAIL,'缺少参数');
        }

        // 验证是否初始化过排序，没有初始化排序就初始化排序
        $res = $this->initializationSort($table,$where,$sortField);
        if($res['code'] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL,$res['msg']);
        }

        $info = $table->where($where)->where(['id' => $id])->first();
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'数据不存在');
        }
        $list = [];
        switch ($action) {
            case 'down':
                $list = $table
                    ->where($where)
                    ->where($sortField,'<',$info[$sortField])
                    ->orderByRaw("$sortField desc")
                    ->first();
                break;
            case 'up':
                $list = $table
                    ->where($where)
                    ->where($sortField,'>',$info[$sortField])
                    ->orderByRaw("$sortField asc")
                    ->first();
                break;
            default:
                return Normal::returnCode(Normal::FAIL,'参数错误');
                break;
        }
        if (!$list) {
            return Normal::returnCode(Normal::FAIL,'操作失败');
        }

        Db::connection('bbc_commodity')->beginTransaction();
        try{
            $table
                ->where(['id' => $info['id']])
                ->update([$sortField => $list[$sortField]]);
            $table
                ->where(['id' => $list['id']])
                ->update([$sortField => $info[$sortField]]);
            Db::connection('bbc_commodity')->commit();
        }catch (\Exception $e){
            Db::connection('bbc_commodity')->rollBack();
            return Normal::returnCode(Normal::FAIL,'移动失败：'.$e->getMessage());
        }
        return Normal::returnCode(Normal::SUC,'移动成功');
    }

    /**
     * 初始化数据库排序
     * $table 实例化的表 $where 查询条件 $sortField 排序字段
     * @return array
     */
    function initializationSort($table,$where,$sortField = 'sort') : array{
        if (empty($table) || empty($where)) {
            return Normal::returnCode(Normal::FAIL,'缺少参数');
        }

        $has = $table->where($where)
            ->groupBy($sortField)
            ->havingRaw("COUNT(*) > 1")
            ->pluck('id')->toArray();
        if(!$has){
            return Normal::returnCode(Normal::SUC,'排序已初始化过');
        }
        $data_list = $table->where($where)
            ->orderByRaw("$sortField desc,id desc")
            ->pluck('id')->toArray();

        $updateData = [];

        $sort_data_list = array_reverse($data_list);
        foreach ($sort_data_list as $k=>$v){
            $updateData[$k] = ['id'=>$v,$sortField=>$k];
        }

        // 批量更新排序
        return (new \Service\MoveUpDownService\UpdateBatchService())->updateBatch($table,$updateData,'id');
    }

    /**
     * 置顶
     * @param $table
     * @param $where
     * @param $id
     * @return array
     */
    public function setTop($id = 0,$table,$where,$sortField = 'sort',$type = 'top') : array{
        if (empty($table) || empty($where) || empty($id)) {
            return Normal::returnCode(Normal::FAIL,'缺少参数');
        }
        if(!in_array($type,['top','bottom'])){
            return Normal::returnCode(Normal::FAIL,'参数错误');
        }

        $info = $table->where($where)->where(['id' => $id])->first();
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'数据不存在');
        }

        // 验证是否初始化过排序，没有初始化排序就初始化排序
        $res = $this->initializationSort($table,$where,$sortField);
        if($res['code'] != Normal::SUC){
            return Normal::returnCode(Normal::FAIL,$res['msg']);
        }

        $data_list = $table->where($where)
            ->orderByRaw("$sortField desc")
            ->pluck('id')->toArray();

        $key = array_keys($data_list,$id);
        unset($data_list[$key[0]]);
        if($type == 'top'){ //置顶
            array_unshift($data_list,$id);
        }else if($type == 'bottom'){ //置底
            $data_list[] = $id;
        }

        $updateData = [];
        $sort_data_list = array_reverse($data_list);
        foreach ($sort_data_list as $k=>$v){
            $updateData[$k] = ['id'=>$v,$sortField=>$k];
        }

        // 批量更新排序
        return (new \Service\MoveUpDownService\UpdateBatchService())->updateBatch($table,$updateData,'id');
    }
}